package com.lianjing.sh.acceleo.controller.tool.service;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.util.URI;
import org.eclipse.uml2.uml.Association;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.internal.impl.DataTypeImpl;
import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.junit.Assert;
import org.junit.Test;

public class NameService{

//			[comment (用户)TB_User -> TB_User /]
//			[query public getNotDealName(namedElement : NamedElement) : String =
//				getNameSub(namedElement)
//			 /]
//
//			[comment ~:toString(), @:emal, ^:唯一, #:电话, &:大数据, $:文件/]
//			[query public getName(namedElement : NamedElement) : String =
//				getNameSub(namedElement).trim().toString()
//					.replace('@', '')
//					.replace('\\^', '')
//					.replace('#', '')
//					.replace('&', '')
//					.replace('\\$', '')
//			 /]
	/**
	 * 后缀：
	 * :! : @javax.persistence.Transient
	 * :~ : toString()
	 * :^ : 唯一
	 * :@ : email
	 * :# : 电话
	 * :* : 密码
	 * :& : Lob
	 *
	 * :+ : 不继承覆盖，即不使用 @Override 注解
	 * :id : 确定为ID
	 * :p : 主表(primary)
	 * :c: @org.springframework.data.annotation.CreatedBy	creator <-> createdXXX
	 * :m: @org.springframework.data.annotation.LastModifiedBy	lastModifier <-> lastModifiedXXX
	 *
	 * :[ or [组名[ : 分组开始
	 * :] : 分组结束
	 *
	 * = : 默认值，必须是最后一个参数
	 */
	private static String name1 = " ( abc ) 123:id!~@*^#&${ img png gif }{ 5bit-50B }{ 50 - 100 * 100 - 200 } [ ( 组名 ) group : c ( 尾巴 ) [] = 'xyz' ( def )";
	private static String name1_1 = " ( abc ) 123:id!~@*^#&$ ]( def ) ";

	private static String name2 = " 123:id!~@*^#&${ img png gif } [ = 'xyz' ( def )";
	private static String name2_1 = " 123:!~@*^#&$ [] ( def )";

	private static String name3 = " ( abc ) 123:!~@*^#&${ }{ 5bit-50B } = 'xyz'  ";
	private static String name3_1 = " ( abc ) 123:id!~@*^#&$[ ( 组名 ) group : c [] ";

	private static String name4 = " 123:id!~@*^#&${ }{ }{ 50 -  * 100 -  } [group ( 尾巴 ) [] = 'xyz'  ";
	private static String name4_1 = " 123:!~@*^#&$] ";

	private static String nameC = " ( abc ) 123:c!~@*^#&${ img png gif }{ 5bit-50B }{ 50 - 100 * 100 - 200 } [( 哈哈 )[] = 'xyz'  ( def ) ";
	private static String nameC_1 = " :c!~@*^#&$[ ( def )";

	private static String name5 = " :c!~@*^#&${} ] ";
	private static String name6 = "( abc )";
	private static String name7 = ":c";

	/**
	 *  (用户)TB_User:id=123(0-50) -> 用户
	 */
	public String getNameHead(NamedElement element){
		return this.getNameHead(element.getName());
	}
	public String getNameHead(String name){
		if(name == null){
			return "";
		}
		name = name.trim();
		if(name.startsWith("(")){
			return name.substring(1, name.indexOf(")")).trim();
		}else{
			return "";
		}
	}
	@Test
	public void testGetNameHead() {
		NameService service = new NameService();
		Assert.assertEquals("abc", service.getNameHead(name1));
		Assert.assertEquals("", service.getNameHead(name2));
		Assert.assertEquals("abc", service.getNameHead(name3));
		Assert.assertEquals("", service.getNameHead(name4));
		Assert.assertEquals("abc", service.getNameHead(nameC));

		Assert.assertEquals("abc", service.getNameHead(name1_1));
		Assert.assertEquals("", service.getNameHead(name2_1));
		Assert.assertEquals("abc", service.getNameHead(name3_1));
		Assert.assertEquals("", service.getNameHead(name4_1));
		Assert.assertEquals("", service.getNameHead(nameC_1));

		Assert.assertEquals("", service.getNameHead(name5));
		Assert.assertEquals("abc", service.getNameHead(name6));
		Assert.assertEquals("", service.getNameHead(name7));
	}

	/**
	 *  (用户)TB_User:!~@^#&${} <?,?> = 'xyz' (0-50) -> TB_User:!~@^#&${} <?,?> = 'xyz'
	 */
	public String getNameBody(NamedElement element){
		return this.getNameBody(element.getName());
	}
	public String getNameBody(String name){
		if(name == null || name.trim().equals("")){
			return "";
		}
		name = name.trim();
		int startIndex = 0;
		if(name.startsWith("(")){
			startIndex = name.indexOf(")")+1;
			if(startIndex>=name.length()){
				return "";
			}
		}
		int endIndex = name.length();
		if(name.endsWith(")")){
			endIndex = name.lastIndexOf("(");
		}else if(name.endsWith("}")){
			if(name.lastIndexOf("(") > 0){
				endIndex = name.lastIndexOf("(");
			}
		}
		return name.substring(startIndex, endIndex).trim();
	}
	@Test
	public void testGetNameBody() {
		NameService service = new NameService();
		Assert.assertEquals("123:id!~@*^#&${ img png gif }{ 5bit-50B }{ 50 - 100 * 100 - 200 } [ ( 组名 ) group : c ( 尾巴 ) [] = 'xyz'", service.getNameBody(name1));
		Assert.assertEquals("123:id!~@*^#&${ img png gif } [ = 'xyz'", service.getNameBody(name2));
		Assert.assertEquals("123:!~@*^#&${ }{ 5bit-50B } = 'xyz'", service.getNameBody(name3));
		Assert.assertEquals("123:id!~@*^#&${ }{ }{ 50 -  * 100 -  } [group ( 尾巴 ) [] = 'xyz'", service.getNameBody(name4));
		Assert.assertEquals("123:c!~@*^#&${ img png gif }{ 5bit-50B }{ 50 - 100 * 100 - 200 } [( 哈哈 )[] = 'xyz'", service.getNameBody(nameC));

		Assert.assertEquals("123:id!~@*^#&$ ]", service.getNameBody(name1_1));
		Assert.assertEquals("123:!~@*^#&$ []", service.getNameBody(name2_1));
		Assert.assertEquals("123:id!~@*^#&$[ ( 组名 ) group : c []", service.getNameBody(name3_1));
		Assert.assertEquals("123:!~@*^#&$]", service.getNameBody(name4_1));
		Assert.assertEquals(":c!~@*^#&$[", service.getNameBody(nameC_1));

		Assert.assertEquals(":c!~@*^#&${} ]", service.getNameBody(name5));
		Assert.assertEquals("", service.getNameBody(name6));
		Assert.assertEquals(":c", service.getNameBody(name7));
	}

	/**
	 * TB_City(1) -> city
	 * TB_City(*) -> cities
	 */
	private String getPropertyNameByType(Property property){
		String pName = this.getTBShortName(property.getType());
		int lowerBound = property.lowerBound();
		int upperBound = property.upperBound();
		if(lowerBound>1 || lowerBound==-1 || upperBound>1 || upperBound==-1){
			if(pName.endsWith("y")){
				pName = pName.substring(0, pName.length()-1) + "ies";
			}else{
				pName = pName+"s";
			}
		}
		pName = pName.substring(0,1).toLowerCase() + pName.substring(1);
		return pName.trim();
	}

	/**
	 * TB_ABC -> ABC
	 */
	public String getTBShortName(NamedElement element){
		String pName = this.getSimpleName(element);
		if(pName.startsWith("TB_")){
			pName = pName.substring(3);
		}
		return pName;
	}

	/**
	 *  " ( abc ) 123:id!~@^#&${} <?,?> = 'xyz' ( def ) " -> "123"
	 */
	public String getSimpleName(Property property){
		String name = this.getSimpleName(property.getName());
		if(null != name && !name.trim().equals("")){
			return name;
		}
		String defaultPropertyName = this.getPropertyNameByType(property);
		//
		if(this.hasNameAttr(property, "c")){
			return "creator";
		}
		if(this.hasNameAttr(property, "m")){
			return "lastModifier";
		}
		//
		Association association = property.getAssociation();
		if(this.getSimpleName(property.getName()).equals("") && null != association){
			for(Property oppositeP : association.getMemberEnds()){
				if(oppositeP == property){
					continue;
				}
				//
				if(this.hasNameAttr(oppositeP, "c")){
					defaultPropertyName = defaultPropertyName.substring(0,1).toUpperCase() + defaultPropertyName.substring(1);
					return "created"+defaultPropertyName;
				}
				if(this.hasNameAttr(oppositeP, "m")){
					defaultPropertyName = defaultPropertyName.substring(0,1).toUpperCase() + defaultPropertyName.substring(1);
					return "lastModified"+defaultPropertyName;
				}
			}
		}
		//
		return defaultPropertyName;
	}
	@SuppressWarnings("restriction")
	public String getSimpleName(NamedElement element){
		// 说明：PrimitiveTypeImpl extends DataTypeImpl
		if(element instanceof DataTypeImpl) {
			URI eProxyURI = ((DataTypeImpl)element).eProxyURI();
			if(null != eProxyURI) {
				String fragment = eProxyURI.fragment();
				if("EString".equals(fragment)) {
					return "String";
				}else if("EBoolean".equals(fragment)) {
					return "Boolean";
				}else if("EInt".equals(fragment)) {
					return "Integer";
				}else if("ELong".equals(fragment)) {
					return "Long";
				}else if("EShort".equals(fragment)) {
					return "Short";
				}else if("EDouble".equals(fragment)) {
					return "Double";
				}else if("EFloat".equals(fragment)) {
					return "Float";
				}else if("EDate".equals(fragment)) {
					return "java.util.Date";
				}else if("EJavaObject".equals(fragment)) {
					return "java.lang.Object";
				}
			}
		}
		return this.getSimpleName(element.getName());
	}
	public String getSimpleName(String name){
		name = this.getNameBody(name);
		if(null != name){
			int end = name.indexOf(":");
			if(end == -1){
				end = name.indexOf("=");
			}
			if(end !=-1){
				name = name.substring(0, end).trim();
			}
//			return name.replaceAll("[!~@*^#&]*", "").replaceAll("\\$(?!\\{)", "");
			return name;
		}else{
			return "";
		}
	}
	@Test
	public void testGetSimpleName() {
		NameService service = new NameService();
		Assert.assertEquals("123", service.getSimpleName(name1));
		Assert.assertEquals("123", service.getSimpleName(name1_1));

		Assert.assertEquals("123", service.getSimpleName(name2));
		Assert.assertEquals("123", service.getSimpleName(name2_1));

		Assert.assertEquals("123", service.getSimpleName(name3));
		Assert.assertEquals("123", service.getSimpleName(name3_1));

		Assert.assertEquals("123", service.getSimpleName(name4));
		Assert.assertEquals("123", service.getSimpleName(name4_1));

		Assert.assertEquals("123", service.getSimpleName(nameC));
		Assert.assertEquals("", service.getSimpleName(nameC_1));

		Assert.assertEquals("", service.getSimpleName(name5));
		Assert.assertEquals("", service.getSimpleName(name6));
		Assert.assertEquals("", service.getSimpleName(name7));
	}

//	/**
//	 *  " ( abc ) 123:id!~@^#&$ <?,?> = 'xyz' ( def ) " -> "123"
//	 *  " ( abc ) :c!~@^#&$ <?,?> = 'xyz' ( def ) " -> "creator"
//	 */
//	public String getName(NamedElement element){
//		return getName(element.getSimpleName());
//	}
//	public String getName(String name){
//		String nameOnly = getNameOnly(name);
//		if(null == nameOnly){
//			return "";
//		}
//		if(!nameOnly.equals("")){
//			return nameOnly;
//		}
//		//
//		if(hasNameAttr(name, "c")){
//			return "creator";
//		}else if(hasNameAttr(name, "m")){
//			return "lastModifier";
//		}else{
//			return "";
//		}
//	}
//	@Test
//	public void testGetName() {
//		Name_Service service = new Name_Service();
//		Assert.assertEquals("123", service.getName(name1));
//		Assert.assertEquals("123", service.getName(name1_1));
//
//		Assert.assertEquals("123", service.getName(name2));
//		Assert.assertEquals("123", service.getName(name2_1));
//
//		Assert.assertEquals("123", service.getName(name3));
//		Assert.assertEquals("123", service.getName(name3_1));
//
//		Assert.assertEquals("123", service.getName(name4));
//		Assert.assertEquals("123", service.getName(name4_1));
//
//		Assert.assertEquals("123", service.getName(nameC));
//		Assert.assertEquals("creator", service.getName(nameC_1));
//	}

	/**
	 *  (用户)TB_User:id!~@^#&$ = 'xyz' (0-50) -> true
	 */
	public Boolean hasNameDefaultValue(NamedElement element){
		return this.hasNameDefaultValue(element.getName());
	}
	public Boolean hasNameDefaultValue(String name){
		name = this.getNameBody(name);
		if(null == name){
			return false;
		}
		if(-1 == name.indexOf("=")){
			return false;
		}
		return true;
	}
	@Test
	public void testHasNameDefaultValue() {
		NameService service = new NameService();
		Assert.assertEquals(true, service.hasNameDefaultValue(name1));
		Assert.assertEquals(false, service.hasNameDefaultValue(name1_1));

		Assert.assertEquals(true, service.hasNameDefaultValue(name2));
		Assert.assertEquals(false, service.hasNameDefaultValue(name2_1));

		Assert.assertEquals(true, service.hasNameDefaultValue(name3));
		Assert.assertEquals(false, service.hasNameDefaultValue(name3_1));

		Assert.assertEquals(true, service.hasNameDefaultValue(name4));
		Assert.assertEquals(false, service.hasNameDefaultValue(name4_1));

		Assert.assertEquals(true, service.hasNameDefaultValue(nameC));
		Assert.assertEquals(false, service.hasNameDefaultValue(nameC_1));

		Assert.assertEquals(false, service.hasNameDefaultValue(name5));
		Assert.assertEquals(false, service.hasNameDefaultValue(name6));
		Assert.assertEquals(false, service.hasNameDefaultValue(name7));
	}

	/**
	 *  (用户)TB_User:id!~@^#&$ = 'xyz' (0-50) -> 'xyz'
	 */
	public String getNameDefaultValue(NamedElement element){
		return this.getNameDefaultValue(element.getName());
	}
	public String getNameDefaultValue(String name){
		name = this.getNameBody(name);
		if(null == name){
			return "";
		}
		int start = name.indexOf("=");
		if(-1 == start){
			return "";
		}
		return name.substring(start+1, name.length()).trim();
	}
	@Test
	public void testGetNameDefaultValue() {
		NameService service = new NameService();
		Assert.assertEquals("'xyz'", service.getNameDefaultValue(name1));
		Assert.assertEquals("", service.getNameDefaultValue(name1_1));

		Assert.assertEquals("'xyz'", service.getNameDefaultValue(name2));
		Assert.assertEquals("", service.getNameDefaultValue(name2_1));

		Assert.assertEquals("'xyz'", service.getNameDefaultValue(name3));
		Assert.assertEquals("", service.getNameDefaultValue(name3_1));

		Assert.assertEquals("'xyz'", service.getNameDefaultValue(name4));
		Assert.assertEquals("", service.getNameDefaultValue(name4_1));

		Assert.assertEquals("'xyz'", service.getNameDefaultValue(nameC));
		Assert.assertEquals("", service.getNameDefaultValue(nameC_1));

		Assert.assertEquals("", service.getNameDefaultValue(name5));
		Assert.assertEquals("", service.getNameDefaultValue(name6));
		Assert.assertEquals("", service.getNameDefaultValue(name7));
	}

	/**
	 *  " ( abc ) 123:id{}!~@^#&${} <?,?> = 'xyz' ( def ) " -> "id{}!~@^#&${}"
	 */
	private String getNameAttrBody(String name){
		name = this.getNameBody(name);
		if(null != name){
			// 开始位置1
			int start_1 = name.indexOf(":");
			if(start_1 == -1){
				return "";
			}
			// 结束位置1
			int end_1 = name.indexOf("[");
			if(end_1 == -1){
				end_1 = name.indexOf("]");
			}
			if(-1==end_1){
				int end_temp = name.indexOf("=");
				if(-1 != end_temp){
					return name.substring(start_1+1, end_temp).trim();
				}
			}
			if(-1==end_1){
				return name.substring(start_1+1).trim();
			}
			String str1 = name.substring(start_1+1, end_1);
			if(name.length() == end_1+1){
				return str1.trim();
			}
			// 开始位置2
			int start_2 = name.lastIndexOf("]");
			if(-1==start_2){
				start_2 = name.lastIndexOf("[");
			}
			if(end_1 == start_2){
				return str1.trim();
			}
			int end_2 = name.indexOf("=");
			// 得到结果
			if(end_2 ==-1){
				return (str1 + name.substring(start_2+1)).trim();
			}else{
				return (str1 + name.substring(start_2+1, end_2)).trim();
			}
		}else{
			return "";
		}
	}
	@Test
	public void testGetNameAttrBody() {
		NameService service = new NameService();
		Assert.assertEquals("id!~@*^#&${ img png gif }{ 5bit-50B }{ 50 - 100 * 100 - 200 }", service.getNameAttrBody(name1));
		Assert.assertEquals("id!~@*^#&$", service.getNameAttrBody(name1_1));

		Assert.assertEquals("id!~@*^#&${ img png gif }", service.getNameAttrBody(name2));
		Assert.assertEquals("!~@*^#&$", service.getNameAttrBody(name2_1));

		Assert.assertEquals("!~@*^#&${ }{ 5bit-50B }", service.getNameAttrBody(name3));
		Assert.assertEquals("id!~@*^#&$", service.getNameAttrBody(name3_1));

		Assert.assertEquals("id!~@*^#&${ }{ }{ 50 -  * 100 -  }", service.getNameAttrBody(name4));
		Assert.assertEquals("!~@*^#&$", service.getNameAttrBody(name4_1));

		Assert.assertEquals("c!~@*^#&${ img png gif }{ 5bit-50B }{ 50 - 100 * 100 - 200 }", service.getNameAttrBody(nameC));
		Assert.assertEquals("c!~@*^#&$", service.getNameAttrBody(nameC_1));

		Assert.assertEquals("c!~@*^#&${}", service.getNameAttrBody(name5));
		Assert.assertEquals("", service.getNameAttrBody(name6));
		Assert.assertEquals("c", service.getNameAttrBody(name7));
	}

	/**
	 * a{ss}c{tt}b -> abc
	 */
	private String clearAttrs(StringBuilder name){
		int start = name.indexOf("{");
		if(-1 == start){
			return name.toString();
		}else{
			int end = name.indexOf("}", start);
			name.delete(start, end+1);
			this.clearAttrs(name);
		}

		return name.toString();
	}
	@Test
	public void testClearAttrs(){
		Assert.assertEquals("abc", this.clearAttrs(new StringBuilder("a{x_1}b{x_2}c")));
		Assert.assertEquals("abc", this.clearAttrs(new StringBuilder("abc")));
		Assert.assertEquals("bc", this.clearAttrs(new StringBuilder("{x_1}b{x_2}c")));
		Assert.assertEquals("ac", this.clearAttrs(new StringBuilder("a{x_1}{x_2}c")));
		Assert.assertEquals("bc", this.clearAttrs(new StringBuilder("{x_1}b{x_2}c")));
		Assert.assertEquals("", this.clearAttrs(new StringBuilder("{x_1}{x_2}")));
	}

	/**
	 *  (" ( abc ) 123:id{}!~@^#&${} <?,?> = 'xyz' ( def ) ", $) -> true
	 */
	public boolean hasNameAttr(NamedElement element, String attrName){
		return this.hasNameAttr(element.getName(), attrName);
	}
	public boolean hasNameAttr(String name, String attrName){
		String attrBody = this.getNameAttrBody(name);
		if("".equals(attrBody)){
			return false;
		}
		return -1 != this.clearAttrs(new StringBuilder(attrBody)).indexOf(attrName);
	}
	@Test
	public void testHasNameAttr() {
		NameService service = new NameService();
		Assert.assertEquals(true, service.hasNameAttr(name1, "id"));
		Assert.assertEquals(true, service.hasNameAttr(name1_1, "id"));

		Assert.assertEquals(true, service.hasNameAttr(name2, "$"));
		Assert.assertEquals(true, service.hasNameAttr(name2_1, "$"));

		Assert.assertEquals(false, service.hasNameAttr(name3, "abc"));
		Assert.assertEquals(false, service.hasNameAttr(name3_1, "abc"));

		Assert.assertEquals(true, service.hasNameAttr(name4, "!"));
		Assert.assertEquals(true, service.hasNameAttr(name4_1, "!"));

		Assert.assertEquals(false, service.hasNameAttr(nameC, "m"));
		Assert.assertEquals(true, service.hasNameAttr(nameC_1, "c"));

		Assert.assertEquals(false, service.hasNameAttr(name5, "]"));
		Assert.assertEquals(false, service.hasNameAttr(name6, "c"));
	}

	/**
	 *  (" ( abc ) 123:id{}!~@^#&${} <?,?> = 'xyz' ( def ) ", id) -> true
	 */
	public boolean startsWithNameAttr(NamedElement element, String attrName){
		return this.startsWithNameAttr(element.getName(), attrName);
	}
	public boolean startsWithNameAttr(String name, String attrName){
		String attrBody = this.getNameAttrBody(name);
		if("".equals(attrBody)){
			return false;
		}
		String str = this.clearAttrs(new StringBuilder(attrBody));
		return str.startsWith(attrName);
	}
	@Test
	public void testStartsWithNameAttr() {
		NameService service = new NameService();
		Assert.assertEquals(true, service.startsWithNameAttr(name1, "id"));
		Assert.assertEquals(true, service.startsWithNameAttr(name1_1, "id"));

		Assert.assertEquals(false, service.startsWithNameAttr(name2, "$"));
		Assert.assertEquals(false, service.startsWithNameAttr(name2_1, "$"));

		Assert.assertEquals(false, service.startsWithNameAttr(name3, "abc"));
		Assert.assertEquals(false, service.startsWithNameAttr(name3_1, "abc"));

		Assert.assertEquals(false, service.startsWithNameAttr(name4, "!"));
		Assert.assertEquals(true, service.startsWithNameAttr(name4_1, "!"));

		Assert.assertEquals(false, service.startsWithNameAttr(nameC, "m"));
		Assert.assertEquals(true, service.startsWithNameAttr(nameC_1, "c"));

		Assert.assertEquals(false, service.startsWithNameAttr(name5, "]"));
		Assert.assertEquals(false, service.startsWithNameAttr(name6, "c"));
	}

	/**
	 *  (" ( abc ) 123:id{}!~@^#&${} <?,?> = 'xyz' ( def ) ", id!~@^#&$) -> true
	 */
	public boolean isNameAttr(NamedElement element, String attrName){
		return this.isNameAttr(element.getName(), attrName);
	}
	public boolean isNameAttr(String name, String attrName){
		String attrBody = this.getNameAttrBody(name);
		if("".equals(attrBody)){
			return false;
		}
		return this.clearAttrs(new StringBuilder(attrBody))
				.trim()
				.equals(attrName.trim());
	}
	@Test
	public void testIsNameAttr() {
		NameService service = new NameService();
		Assert.assertEquals(true, service.isNameAttr(name1, "id!~@*^#&$"));
		Assert.assertEquals(false, service.isNameAttr(name1_1, "id"));

		Assert.assertEquals(true, service.isNameAttr(name2, "id!~@*^#&$"));
		Assert.assertEquals(false, service.isNameAttr(name2_1, "$"));

		Assert.assertEquals(true, service.isNameAttr(name3, "!~@*^#&$"));
		Assert.assertEquals(false, service.isNameAttr(name3_1, "abc"));

		Assert.assertEquals(true, service.isNameAttr(name4, "id!~@*^#&$"));
		Assert.assertEquals(true, service.isNameAttr(name4_1, "!~@*^#&$"));

		Assert.assertEquals(false, service.isNameAttr(nameC, "m"));
		Assert.assertEquals(true, service.isNameAttr(nameC_1, "c!~@*^#&$"));

		Assert.assertEquals(false, service.isNameAttr(name5, "c!~@*^#&${}"));
		Assert.assertEquals(false, service.isNameAttr(name6, "c"));
	}

	/**
	 *  getNameAttrParas(" ( abc ) 123:id{}!~@^#&${aaa}{bbb}{ccc} <?,?> = 'xyz' ( def ) ", $) -> [aaa, bbb, ccc]
	 */
	public List<String> getNameAttrParas(NamedElement element, String attrName){
		return this.getNameAttrParas(element.getName(), attrName);
	}
	public List<String> getNameAttrParas(String name, String attrName){
		List<String> arrs = new ArrayList<>();
		String attrBody = this.getNameAttrBody(name);
		if("".equals(attrBody)){
			return arrs;
		}
		int start = this.clearAttrs(new StringBuilder(attrBody)).indexOf(attrName);
		if(-1 == start){
			return arrs;
		}
		this.para(attrBody, start, arrs);
		return arrs;
	}
	/** ${aaa}{bbb}{ccc} -> [aaa, bbb, ccc] */
	private void para(String str, int start, List<String> arrs){
		if(str.length()<=start+1){
			return;
		}
		if('{' != str.charAt(start+1)){
			return;
		}
		int end = str.indexOf("}", start+1);
		arrs.add(str.substring(start+2, end).trim());
		this.para(str, end, arrs);
	}
	@Test
	public void testGetNameAttrParas() {
		NameService service = new NameService();
		MatcherAssert.assertThat(service.getNameAttrParas(name1, "$"), CoreMatchers.hasItems("img png gif", "5bit-50B", "50 - 100 * 100 - 200"));
		MatcherAssert.assertThat(service.getNameAttrParas(name1_1, "id").isEmpty(), CoreMatchers.is(true));

		MatcherAssert.assertThat(service.getNameAttrParas(name2, "$"), CoreMatchers.hasItems("img png gif"));
		MatcherAssert.assertThat(service.getNameAttrParas(name2_1, "$").isEmpty(), CoreMatchers.is(true));

		MatcherAssert.assertThat(service.getNameAttrParas(name3, "abc").isEmpty(), CoreMatchers.is(true));
		MatcherAssert.assertThat(service.getNameAttrParas(name3_1, "abc").isEmpty(), CoreMatchers.is(true));

		MatcherAssert.assertThat(service.getNameAttrParas(name4, "!").isEmpty(), CoreMatchers.is(true));
		MatcherAssert.assertThat(service.getNameAttrParas(name4_1, "!").isEmpty(), CoreMatchers.is(true));

		MatcherAssert.assertThat(service.getNameAttrParas(nameC, "c").isEmpty(), CoreMatchers.is(true));
		MatcherAssert.assertThat(service.getNameAttrParas(nameC_1, "c").isEmpty(), CoreMatchers.is(true));

		MatcherAssert.assertThat(service.getNameAttrParas(name5, "c").isEmpty(), CoreMatchers.is(true));
		MatcherAssert.assertThat(service.getNameAttrParas(name6, "c").isEmpty(), CoreMatchers.is(true));
	}

//	/**
//	 *  " ( abc ) 123:id!~@^#&$ < ? , ? > = 'xyz' ( def ) " -> [?,?]
//	 */
//	public List<String> getGenericNames(NamedElement element){
//		return getGenericNames(element.getSimpleName());
//	}
//	public List<String> getGenericNames(String name){
//		List<String> list = new ArrayList<>();
//		name = this.getNameBody(name);
//		if(null != name){
//			int start = name.indexOf("<");
//			if(start != -1){
//				for(String item : name.substring(start+1, name.indexOf(">")).split(",")){
//					list.add(item.trim());
//				}
//			}
//		}
//		return list;
//	}
//	@Test
//	public void testGetGenericNames() {
//		Name_Service service = new Name_Service();
//		Assert.assertEquals("?", service.getGenericNames(name1).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name1).get(1));
//		Assert.assertEquals("?", service.getGenericNames(name1_1).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name1_1).get(1));
//
//		Assert.assertEquals("?", service.getGenericNames(name2).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name2).get(1));
//		Assert.assertEquals("?", service.getGenericNames(name2_1).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name2_1).get(1));
//
//		Assert.assertEquals("?", service.getGenericNames(name3).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name3).get(1));
//		Assert.assertEquals("?", service.getGenericNames(name3_1).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name3_1).get(1));
//
//		Assert.assertEquals("?", service.getGenericNames(name4).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name4).get(1));
//		Assert.assertEquals("?", service.getGenericNames(name4_1).get(0));
//		Assert.assertEquals("?", service.getGenericNames(name4_1).get(1));
//
//		Assert.assertEquals("?", service.getGenericNames(nameC).get(0));
//		Assert.assertEquals("?", service.getGenericNames(nameC).get(1));
//		Assert.assertEquals("?", service.getGenericNames(nameC_1).get(0));
//		Assert.assertEquals("?", service.getGenericNames(nameC_1).get(1));
//	}

	/**
	 *	(用户)TB_User:id=123(0-50) -> 0-50
	 */
	public String getNameTail(NamedElement element){
		return this.getNameTail(element.getName());
	}
	public String getNameTail(String name){
		if(name == null){
			return "";
		}
		name = name.trim();
		String temp = "";
		//
		if(name.endsWith(")")){
			int end = name.lastIndexOf("(");
			if(end==0){
				return "";
			}
			temp = name.substring(end+1, name.length()-1);
		}else{
			return "";
		}
//		else if(name.endsWith("}")){
//			if(name.lastIndexOf("(") > 0){
//				temp = name.substring(name.lastIndexOf("(")+1, name.lastIndexOf(")"));
//			}else{
//				temp = "";
//			}
//		}
		return temp.trim();
	}
	@Test
	public void testGetNameTail() {
		NameService service = new NameService();
		Assert.assertEquals("def", service.getNameTail(name1));
		Assert.assertEquals("def", service.getNameTail(name2));
		Assert.assertEquals("", service.getNameTail(name3));
		Assert.assertEquals("", service.getNameTail(name4));
		Assert.assertEquals("def", service.getNameTail(nameC));

		Assert.assertEquals("def", service.getNameTail(name1_1));
		Assert.assertEquals("def", service.getNameTail(name2_1));
		Assert.assertEquals("", service.getNameTail(name3_1));
		Assert.assertEquals("", service.getNameTail(name4_1));
		Assert.assertEquals("def", service.getNameTail(nameC_1));

		Assert.assertEquals("", service.getNameTail(name5));
		Assert.assertEquals("", service.getNameTail(name6));
	}

	/**
	 *  (用户)TB_User:id=123(0-50) -> 用户
	 *  (用户)TB_User:c=123(0-50) -> 用户
	 *  (用户):c=123(0-50) -> 用户
	 *  TB_User:c=123(0-50) -> 创建者
	 *  TB_User:m=123(0-50) -> 最后修改者
	 */
	public String getNameComment(Property property){
		String comment = this.getNameHead(property.getName());
		if(!comment.trim().equals("")){
			return comment;
		}
		comment = this.getNameHead(property.getType());
		//
		if(this.hasNameAttr(property, "c")){
			return "创建者";
		}
		if(this.hasNameAttr(property, "m")){
			return "最后修改者";
		}
		//
		Association association = property.getAssociation();
		if(this.getNameHead(property.getName()).equals("") && null != association){
			for(Property oppositeP : association.getMemberEnds()){
				if(oppositeP == property){
					continue;
				}
				//
				if(this.hasNameAttr(oppositeP, "c")){
					return "创建的"+comment;
				}
				if(this.hasNameAttr(oppositeP, "m")){
					return "最后修改的"+comment;
				}
			}
		}
		//
		return comment;
	}

	/**
	 * 判断是否有 NameComment
	 */
	public Boolean hasNameComment(Property property){
		String name = property.getName();
		if(name == null){
			return false;
		}
		name = name.trim();
		if(name.startsWith("(")){
			return true;
		}else{
			return false;
		}
	}

	/**
	 * 组开始
	 *	(用户)TB_User:[(组名)group:c[]=123(0-50) -> [(组名)group:c[]
	 *	(用户)TB_User:[=123(0-50) -> [
	 */
	private String getNameGroup(String name){
		if(name == null){
			return "";
		}
		String attrBody = this.getNameBody(name);
		if(attrBody.equals("")){
			return "";
		}
		// start
		int start = attrBody.indexOf("[");
		if(-1 == start){
			start = attrBody.indexOf("]");
		}
		if(-1 == start){
			return "";
		}
		// end
		int end = attrBody.lastIndexOf("]");
		if(-1 == end){
			end = attrBody.lastIndexOf("[");
		}
		if(-1 == end){
			return attrBody.substring(start, attrBody.length()).trim();
		}
		return attrBody.substring(start, end+1).trim();
	}
	@Test
	public void testGetNameGroup() {
		NameService service = new NameService();
		Assert.assertEquals("[ ( 组名 ) group : c ( 尾巴 ) []", service.getNameGroup(name1));
		Assert.assertEquals("[", service.getNameGroup(name2));
		Assert.assertEquals("", service.getNameGroup(name3));
		Assert.assertEquals("[group ( 尾巴 ) []", service.getNameGroup(name4));
		Assert.assertEquals("[( 哈哈 )[]", service.getNameGroup(nameC));

		Assert.assertEquals("]", service.getNameGroup(name1_1));
		Assert.assertEquals("[]", service.getNameGroup(name2_1));
		Assert.assertEquals("[ ( 组名 ) group : c []", service.getNameGroup(name3_1));
		Assert.assertEquals("]", service.getNameGroup(name4_1));
		Assert.assertEquals("[", service.getNameGroup(nameC_1));

		Assert.assertEquals("]", service.getNameGroup(name5));
		Assert.assertEquals("", service.getNameGroup(name6));
	}

	/**
	 * 组开始
	 *	(用户)TB_User:[组名[=123(0-50) -> true
	 *	(用户)TB_User:[=123(0-50) -> true
	 */
	public Boolean isNameGroupStart(NamedElement element){
		return this.isNameGroupStart(element.getName());
	}
	public Boolean isNameGroupStart(String name){
		if(name == null){
			return false;
		}
		String attrBody = this.getNameGroup(name);
		if(attrBody.equals("")){
			return false;
		}
		return attrBody.indexOf("[") != -1;
	}
	@Test
	public void testIsNameGroupStart() {
		NameService service = new NameService();
		Assert.assertEquals(true, service.isNameGroupStart(name1));
		Assert.assertEquals(true, service.isNameGroupStart(name2));
		Assert.assertEquals(false, service.isNameGroupStart(name3));
		Assert.assertEquals(true, service.isNameGroupStart(name4));
		Assert.assertEquals(true, service.isNameGroupStart(nameC));

		Assert.assertEquals(false, service.isNameGroupStart(name1_1));
		Assert.assertEquals(true, service.isNameGroupStart(name2_1));
		Assert.assertEquals(true, service.isNameGroupStart(name3_1));
		Assert.assertEquals(false, service.isNameGroupStart(name4_1));
		Assert.assertEquals(true, service.isNameGroupStart(nameC_1));

		Assert.assertEquals(false, service.isNameGroupStart(name5));
		Assert.assertEquals(false, service.isNameGroupStart(name6));
	}

	/**
	 * 组结束
	 *	(用户)TB_User:]=123(0-50) -> true
	 */
	public Boolean isNameGroupEnd(NamedElement element){
		return this.isNameGroupEnd(element.getName());
	}
	public Boolean isNameGroupEnd(String name){
		if(name == null){
			return false;
		}
		String attrBody = this.getNameGroup(name);
		if(attrBody.equals("")){
			return false;
		}
		return attrBody.indexOf("]") != -1;
	}
	@Test
	public void testIsNameGroupEnd() {
		NameService service = new NameService();
		Assert.assertEquals(true, service.isNameGroupEnd(name1));
		Assert.assertEquals(false, service.isNameGroupEnd(name2));
		Assert.assertEquals(false, service.isNameGroupEnd(name3));
		Assert.assertEquals(true, service.isNameGroupEnd(name4));
		Assert.assertEquals(true, service.isNameGroupEnd(nameC));

		Assert.assertEquals(true, service.isNameGroupEnd(name1_1));
		Assert.assertEquals(true, service.isNameGroupEnd(name2_1));
		Assert.assertEquals(true, service.isNameGroupEnd(name3_1));
		Assert.assertEquals(true, service.isNameGroupEnd(name4_1));
		Assert.assertEquals(false, service.isNameGroupEnd(nameC_1));

		Assert.assertEquals(true, service.isNameGroupEnd(name5));
		Assert.assertEquals(false, service.isNameGroupEnd(name6));
	}

	/**
	 * 得到组头
	 *	(用户)TB_User:[(组名)group[=123(0-50) -> 组名
	 */
	public String getNameGroupHead(NamedElement element){
		return this.getNameGroupHead(element.getName());
	}
	public String getNameGroupHead(String name){
		String nameGroup = this.getNameGroup(name);
		if(nameGroup.equals("")){
			return "";
		}
		if(nameGroup.startsWith("[")){
			nameGroup = nameGroup.substring(1, nameGroup.length());
		}
		return this.getNameHead(nameGroup);
	}
	@Test
	public void testGetNameGroupHead() {
		NameService service = new NameService();
		Assert.assertEquals("组名", service.getNameGroupHead(name1));
		Assert.assertEquals("", service.getNameGroupHead(name2));
		Assert.assertEquals("", service.getNameGroupHead(name3));
		Assert.assertEquals("", service.getNameGroupHead(name4));
		Assert.assertEquals("哈哈", service.getNameGroupHead(nameC));

		Assert.assertEquals("", service.getNameGroupHead(name1_1));
		Assert.assertEquals("", service.getNameGroupHead(name2_1));
		Assert.assertEquals("组名", service.getNameGroupHead(name3_1));
		Assert.assertEquals("", service.getNameGroupHead(name4_1));
		Assert.assertEquals("", service.getNameGroupHead(nameC_1));

		Assert.assertEquals("", service.getNameGroupHead(name5));
		Assert.assertEquals("", service.getNameGroupHead(name6));
	}

	/**
	 * 得到组体
	 *	(用户)TB_User:[(组名)group:c[=123(0-50) -> group:c
	 */
	private String getNameGroupBody(String name){
		String nameGroup = this.getNameGroup(name);
		if(nameGroup.equals("")){
			return "";
		}
		if(nameGroup.startsWith("[")){
			nameGroup = nameGroup.substring(1, nameGroup.length());
		}
		if(nameGroup.endsWith("[]")){
			nameGroup = nameGroup.substring(0, nameGroup.length()-2);
		}else if(nameGroup.endsWith("[")){
			nameGroup = nameGroup.substring(0, nameGroup.length()-1);
		}else if(nameGroup.endsWith("]")){
			nameGroup = nameGroup.substring(0, nameGroup.length()-1);
		}
		return this.getNameBody(nameGroup);
	}
	@Test
	public void testGetNameGroupBody() {
		NameService service = new NameService();
		Assert.assertEquals("group : c", service.getNameGroupBody(name1));
		Assert.assertEquals("", service.getNameGroupBody(name2));
		Assert.assertEquals("", service.getNameGroupBody(name3));
		Assert.assertEquals("group", service.getNameGroupBody(name4));
		Assert.assertEquals("", service.getNameGroupBody(nameC));

		Assert.assertEquals("", service.getNameGroupBody(name1_1));
		Assert.assertEquals("", service.getNameGroupBody(name2_1));
		Assert.assertEquals("group : c", service.getNameGroupBody(name3_1));
		Assert.assertEquals("", service.getNameGroupBody(name4_1));
		Assert.assertEquals("", service.getNameGroupBody(nameC_1));

		Assert.assertEquals("", service.getNameGroupBody(name5));
		Assert.assertEquals("", service.getNameGroupBody(name6));
	}

	/**
	 * 得到组名称
	 *	(用户)TB_User:[(组名)group:c[=123(0-50) -> group
	 */
	public String getNameGroupName(NamedElement element){
		return this.getNameGroupName(element.getName());
	}
	public String getNameGroupName(String name){
		String body = this.getNameGroupBody(name);
		int start = body.indexOf(":");
		if(start==-1){
			return body.trim();
		}
		return body.substring(0, start).trim();
	}
	@Test
	public void testGetNameGroupName() {
		NameService service = new NameService();
		Assert.assertEquals("group", service.getNameGroupName(name1));
		Assert.assertEquals("", service.getNameGroupName(name2));
		Assert.assertEquals("", service.getNameGroupName(name3));
		Assert.assertEquals("group", service.getNameGroupName(name4));
		Assert.assertEquals("", service.getNameGroupName(nameC));

		Assert.assertEquals("", service.getNameGroupName(name1_1));
		Assert.assertEquals("", service.getNameGroupName(name2_1));
		Assert.assertEquals("group", service.getNameGroupName(name3_1));
		Assert.assertEquals("", service.getNameGroupName(name4_1));
		Assert.assertEquals("", service.getNameGroupName(nameC_1));

		Assert.assertEquals("", service.getNameGroupName(name5));
		Assert.assertEquals("", service.getNameGroupName(name6));
	}

	/**
	 * 得到组参数体
	 *	(用户)TB_User:[(组名)group:cdef[=123(0-50) -> cdef
	 */
	private String getNameGroupAttrBody(String name){
		String body = this.getNameGroupBody(name);
		int start = body.indexOf(":");
		if(start == -1){
			return "";
		}
		if(start==0 && body.length()==1){
			return "";
		}
		return body.substring(start+1).trim();
	}
	@Test
	public void testGetNameGroupAttrBody() {
		NameService service = new NameService();
		Assert.assertEquals("c", service.getNameGroupAttrBody(name1));
		Assert.assertEquals("", service.getNameGroupAttrBody(name1_1));

		Assert.assertEquals("", service.getNameGroupAttrBody(name2));
		Assert.assertEquals("", service.getNameGroupAttrBody(name2_1));

		Assert.assertEquals("", service.getNameGroupAttrBody(name3));
		Assert.assertEquals("c", service.getNameGroupAttrBody(name3_1));

		Assert.assertEquals("", service.getNameGroupAttrBody(name4));
		Assert.assertEquals("", service.getNameGroupAttrBody(name4_1));

		Assert.assertEquals("", service.getNameGroupAttrBody(nameC));
		Assert.assertEquals("", service.getNameGroupAttrBody(nameC_1));

		Assert.assertEquals("", service.getNameGroupAttrBody(name5));
		Assert.assertEquals("", service.getNameGroupAttrBody(name6));
		Assert.assertEquals("", service.getNameGroupAttrBody(name7));
	}

	/**
	 * hasNameGroupAttr
	 */
	public boolean hasNameGroupAttr(NamedElement element, String attrName){
		return this.hasNameGroupAttr(element.getName(), attrName);
	}
	public boolean hasNameGroupAttr(String name, String attrName){
		String attrBody = this.getNameGroupAttrBody(name);
		if("".equals(attrBody)){
			return false;
		}
		return -1 != this.clearAttrs(new StringBuilder(attrBody)).indexOf(attrName);
	}
	@Test
	public void testHasNameGroupAttr() {
		NameService service = new NameService();
		Assert.assertEquals(true, service.hasNameGroupAttr(name1, "c"));
		Assert.assertEquals(false, service.hasNameGroupAttr(name1_1, "c"));

		Assert.assertEquals(false, service.hasNameGroupAttr(name2, "c"));
		Assert.assertEquals(false, service.hasNameGroupAttr(name2_1, "c"));

		Assert.assertEquals(false, service.hasNameGroupAttr(name3, "c"));
		Assert.assertEquals(true, service.hasNameGroupAttr(name3_1, "c"));

		Assert.assertEquals(false, service.hasNameGroupAttr(name4, "c"));
		Assert.assertEquals(false, service.hasNameGroupAttr(name4_1, "c"));

		Assert.assertEquals(false, service.hasNameGroupAttr(nameC, "c"));
		Assert.assertEquals(false, service.hasNameGroupAttr(nameC_1, "c"));

		Assert.assertEquals(false, service.hasNameGroupAttr(name5, "c"));
		Assert.assertEquals(false, service.hasNameGroupAttr(name6, "c"));
	}

	/**
	 * 得到组尾
	 *	(用户)TB_User:[(组名)group(组尾)[=123(0-50) -> 组尾
	 */
	public String getNameGroupTail(NamedElement element){
		return this.getNameGroupTail(element.getName());
	}
	public String getNameGroupTail(String name){
		String nameGroup = this.getNameGroup(name);
		if(nameGroup.equals("")){
			return "";
		}
		if(nameGroup.endsWith("[]")){
			nameGroup = nameGroup.substring(0, nameGroup.length()-2);
		}else if(nameGroup.endsWith("[")){
			nameGroup = nameGroup.substring(0, nameGroup.length()-1);
		}
		if(nameGroup.startsWith("[")){
			nameGroup = nameGroup.substring(1, nameGroup.length());
		}
		return this.getNameTail(nameGroup.trim());
	}
	@Test
	public void testNameGroupTail() {
		NameService service = new NameService();
		Assert.assertEquals("尾巴", service.getNameGroupTail(name1));
		Assert.assertEquals("", service.getNameGroupTail(name2));
		Assert.assertEquals("", service.getNameGroupTail(name3));
		Assert.assertEquals("尾巴", service.getNameGroupTail(name4));
		Assert.assertEquals("", service.getNameGroupTail(nameC));

		Assert.assertEquals("", service.getNameGroupTail(name1_1));
		Assert.assertEquals("", service.getNameGroupTail(name2_1));
		Assert.assertEquals("", service.getNameGroupTail(name3_1));
		Assert.assertEquals("", service.getNameGroupTail(name4_1));
		Assert.assertEquals("", service.getNameGroupTail(nameC_1));

		Assert.assertEquals("", service.getNameGroupTail(name5));
		Assert.assertEquals("", service.getNameGroupTail(name6));
	}

}
